import D from "../test/Data"
import manager from "../test/Astar/manager";
import { Box, Box_Type } from "../test/Astar/box";
import MT from "../test/test/moveto";

export default class SceneLogic extends Laya.Script {

    //地图相关信息
    public beginX: number = 10;
    public beginY: number = 10;
    public offsetX: number = 1;
    public offsetY: number = 1;
    private mapW: number = 16;
    private mapH: number = 30;
    private m_scene: Laya.Scene3D;
    private list: Laya.Sprite3D;
    private beginPos: Laya.Vector2;
    private endPos: Laya.Vector2;
    private pathArray: Array<Box> = new Array<Box>();

    //射线
    private camera: Laya.Camera;
    private ray: Laya.Ray;
    private outHitResult: Laya.HitResult = new Laya.HitResult();
    private outs: Array<Laya.HitResult> = new Array<Laya.HitResult>();
    private point: Laya.Vector2 = new Laya.Vector2();

    //围栏
    private one: Laya.Vector3;
    private two: Laya.Vector3;
    private PlankFences: Laya.Sprite3D = new Laya.Sprite3D;
    private PlankFencesArr: Array<Laya.Sprite3D> = new Array<Laya.Sprite3D>();
    private blowIndex: number = 0;

    //锤子
    private m_hammer: Laya.Sprite3D = new Laya.Sprite3D;

    //存放地面数据
    private cubes: Map<string, Laya.Sprite3D> = new Map<string, Laya.Sprite3D>();

    //羊和狼
    private m_sheep: Laya.Sprite3D;
    private m_wolf: Laya.Sprite3D = new Laya.Sprite3D;
    private sheepMap: Map<Laya.Sprite3D, string> = new Map<Laya.Sprite3D, string>();
    private wolfMap: Map<Laya.Sprite3D, string> = new Map<Laya.Sprite3D, string>();
    private sheepAni: Laya.Animator = new Laya.Animator;
    private wolfAni: Laya.Animator = new Laya.Animator;

    //障碍判断
    private obstaclesone: string;
    private obstaclesArr: Array<Box> = new Array<Box>();

    //狼抓羊移动
    private moveIndex: number = 0;

    //判断
    private JudgeGameResults: number = 0;

    constructor() {
        super();
        let resource = ["3dres/Conventional/model_PlankFences_1.lh",
            "3dres/Conventional/list.lh",
            "3dres/Conventional/sheep.lh",
            "3dres/Conventional/wolf_1.lh",
            "3dres/Conventional/hammer.lh",
            "3dres/Conventional/Assets/Scene/Animation/ani_sheep-die.lani"
        ];
        Laya.loader.create(resource, Laya.Handler.create(this, this.onPreLoadFinish));
        this.m_scene = Laya.stage.getChildAt(0) as Laya.Scene3D;
        this.camera = this.m_scene.getChildAt(1) as Laya.Camera;
        Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.ms_MD);
        Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.ms_MM);
        Laya.stage.on(Laya.Event.MOUSE_UP, this, this.ms_MU);
        this.ray = new Laya.Ray(new Laya.Vector3(0, 0, 0), new Laya.Vector3(0, 0, 0));
    }

    private onPreLoadFinish() {
        this.PlankFences = Laya.loader.getRes("3dres/Conventional/model_PlankFences_1.lh");
        this.m_sheep = Laya.loader.getRes("3dres/Conventional/sheep.lh");
        this.m_wolf = Laya.loader.getRes("3dres/Conventional/wolf_1.lh");
        this.m_hammer = Laya.loader.getRes("3dres/Conventional/hammer.lh");
        this.m_hammer.transform.position = new Laya.Vector3(-2000, -2000, -2000);
        this.m_scene.addChild(this.m_hammer);
        this.sheepAni = this.m_sheep.getChildAt(0).getComponent(Laya.Animator);
        this.wolfAni = this.m_wolf.getChildAt(0).getComponent(Laya.Animator);
        console.log(this.wolfAni);
        this.define_name();
    }

    onEnable(): void {
        this.InitData();
        this.InitEvent();
    }

    onUpdate(): void {
        if (this.JudgeGameResults == 1) {
            if (this.pathArray != null) {
                this.wolfAni.play("run");
                this.move();
            } else {
                this.sheepAni.play("win");
                this.Win();
            }
        }
        else if (this.JudgeGameResults == -1) {
            this.wolfAni.play("attack");
        }
    }

    onDisable(): void {
    }

    wakeup(): void {
    }

    sleep(): void {
    }

    private InitData() {
        manager.Intance.initMapInfo(this.mapW, this.mapH);
    }

    private InitEvent() {
        Laya.stage.on(D.SceneNextStep_Event, this, this.OnNextBtn);
        Laya.stage.on(Laya.Event.KEY_DOWN, this, this.StageClick);
        Laya.stage.on(D.SceneBlow_Event, this, this.blow);
    }

    private define_name() {
        this.list = Laya.Loader.getRes("3dres/Conventional/list.lh") as Laya.Sprite3D;
        this.m_scene.addChild(this.list) as Laya.Sprite3D;
        for (let i = 0; i < this.list.numChildren - 1; i++) {
            let f = Math.floor(i % this.mapW);
            let e = Math.floor(i / this.mapW);
            let obj = new Laya.Sprite3D;
            obj = this.list.getChildAt(i) as Laya.Sprite3D;
            obj.name = f + "_" + e;
            this.cubes.set(obj.name, obj);
        }
        this.InitSheep();
        this.InitWolf();
    }

    private ms_MD() {
        this.point.x = Laya.MouseManager.instance.mouseX;
        this.point.y = Laya.MouseManager.instance.mouseY;
        this.getRay();
        //如果碰撞到物体
        if (this.outs.length != 0 && this.outs[0].collider.owner.name != null) {
            this.one = new Laya.Vector3(this.outs[0].point.x, 0, this.outs[0].point.z);
            this.PlankFences.transform.position = this.one;
            this.m_scene.addChild(this.PlankFences);
            this.getboxs();
        }
    }

    private ms_MM() {
        this.point.x = Laya.MouseManager.instance.mouseX;
        this.point.y = Laya.MouseManager.instance.mouseY;
        this.getRay();
        //如果碰撞到物体
        if (this.outs.length != 0 && this.outs[0].collider.owner.name != null) {
            this.two = new Laya.Vector3(this.outs[0].point.x, 0, this.outs[0].point.z);
            if (this.one && this.two) {
                let d = this.getDistance();
                if (d > 1) {
                    this.getboxs();
                    this.creatPlankFences();
                }
            }
        }
    }

    private ms_MU() {
        this.creatObstacles();
        this.one = null;
        this.two = null;
        this.PlankFences.transform.position = new Laya.Vector3(-20, -20, -20);
        this.NextStep();
    }

    private getRay() {
        //产生射线
        this.camera.viewportPointToRay(this.point, this.ray);
        //拿到射线碰撞的物体
        this.m_scene.physicsSimulation.rayCastAll(this.ray, this.outs);
    }

    private getDistance(): number {
        let dx: number = this.one.x - this.two.x;
        let dz: number = this.one.z - this.two.z;
        this.PlankFences.transform.lookAt(this.two, new Laya.Vector3(0, 1, 0));
        let distance: number = Math.sqrt(dx * dx + dz * dz);
        return distance;
    }

    private creatPlankFences() {
        let c = Laya.Sprite3D.instantiate(this.PlankFences, this.m_scene, true, this.PlankFences.transform.position, this.PlankFences.transform.rotation);
        this.PlankFencesArr.push(c);
        this.one = this.two;
        this.PlankFences.transform.position = this.one;
    }

    private creatObstacles() {
        if (this.obstaclesArr.length > 1) {
            for (let i in this.obstaclesArr) {
                if (this.obstaclesArr[i].type != Box_Type.stop) {
                    this.obstaclesArr[i].type = Box_Type.stop;
                }
            }
        }
    }

    private InitSheep() {
        let f = Math.floor(Math.random() * (this.mapW - 1));
        let l = Math.floor(Math.random() * (this.mapH - 1));
        let s: string = f + "_" + l;
        let obj: Laya.Sprite3D = new Laya.Sprite3D;
        obj = this.cubes.get(s) as Laya.Sprite3D;
        this.m_sheep.transform.position = obj.transform.position;
        this.m_sheep.name = "sheep";
        this.m_scene.addChild(this.m_sheep);
        this.sheepAni.play("idle");
        this.sheepMap.set(this.m_sheep, s);
    }

    private InitWolf() {
        let f = Math.floor(Math.random() * (this.mapW - 1));
        let l = Math.floor(Math.random() * (this.mapH - 1));
        let s: string = f + "_" + l;
        let obj: Laya.Sprite3D = new Laya.Sprite3D;
        obj = this.cubes.get(s) as Laya.Sprite3D;
        this.m_wolf.transform.position = obj.transform.position;
        this.m_wolf.name = "wolf";
        this.m_scene.addChild(this.m_wolf);
        this.wolfAni.play("idle");
        this.wolfMap.set(this.m_wolf, s);
    }

    private getboxs() {
        this.obstaclesone = this.outs[0].collider.owner.name;
        let str: string[];
        str = this.obstaclesone.split("_");
        let f = Number(str[0]);
        let l = Number(str[1]);
        this.obstaclesArr.push(manager.Intance.boxs[f][l]);
    }

    private getSheepStr() {
        let str: string[];
        str = this.sheepMap.get(this.m_sheep).split("_");
        let f = Number(str[0]);
        let l = Number(str[1]);
        this.endPos = new Laya.Vector2(f, l);
    }

    private getWlofStr() {
        let str: string[];
        str = this.wolfMap.get(this.m_wolf).split("_");
        let f = Number(str[0]);
        let l = Number(str[1]);
        this.beginPos = new Laya.Vector2(f, l);
    }

    private findPath() {
        this.getSheepStr();
        this.getWlofStr();
        this.pathArray = manager.Intance.FindPath(this.beginPos, this.endPos);
    }

    private move() {
        let i = this.moveIndex;
        if (i < this.pathArray.length) {
            let processstr = this.pathArray[i].x + "_" + this.pathArray[i].y;
            let process: Laya.Sprite3D = new Laya.Sprite3D();
            process = this.cubes.get(processstr);
            this.m_wolf.transform.lookAt(((process.transform.position) as Laya.Vector3), new Laya.Vector3(0, 1, 0));
            MT.onPositionMoveTo(this.m_wolf, process.transform.position, 0.1, null, this, this.onIndex);
        }
        else {
            this.sheepAni.play("die");
            this.wolfAni.play("attack");
            this.Lose();
            this.JudgeGameResults = -1;
        }
    }

    private onIndex() {
        this.moveIndex++;
    }

    private blow() {
        if (this.blowIndex < this.PlankFencesArr.length) {
            let p = this.PlankFencesArr[this.blowIndex] as Laya.Sprite3D;
            this.m_hammer.transform.position = p.transform.position;
            this.m_hammer.transform.rotation = p.transform.rotation;
            this.PlankFencesArr[this.blowIndex].transform.position
                = new Laya.Vector3(p.transform.position.x, p.transform.position.y - 0.5, p.transform.position.z);
            this.blowIndex++;
        }
        else {
            Laya.stage.off(D.SceneBlow_Event, this, this.blow);
            this.findPath();
            this.JudgeGameResults = 1;
            Laya.stage.event(D.All_Event);
        }
    }

    private Lose() {
        Laya.stage.event(D.Lose_Event);
    }

    private Win() {
        Laya.stage.event(D.Win_Event);
    }

    private Gui() {
        Laya.stage.event(D.Gui_Event);
    }

    private NextStep() {
        Laya.stage.event(D.NextStep_Event);
    }

    private OnNextBtn() {
        this.Gui();
    }

    private getRotat(xx: number, yy: number, obl?: number) {
        // 方法一：asin()
        // var rad:Number = xx > 0 ? ((Math.PI * 3)/2  + Math.asin(-yy/obl)) : (Math.PI / 2 -  Math.asin(-yy/obl));

        // 方法二：acos()
        //var rad:Number = yy < 0 ? Math.acos(xx / obl) : (Math.PI * 2- Math.acos(xx / obl));

        // 方法三：atan2()
        var rad: number = yy < 0 ? Math.atan2(-yy, xx) : Math.PI * 2 + Math.atan2(-yy, xx);
        return rad;
    }

    //测试
    private StageClick(e: Laya.Event) {
        switch (e.keyCode) {
            case Laya.Keyboard.A:
                Laya.stage.event(D.Lose_Event);
                break;
            case Laya.Keyboard.S:
                Laya.stage.event(D.Win_Event);
                break;
            case Laya.Keyboard.D:
                Laya.stage.event(D.Gui_Event);
                break;
            case Laya.Keyboard.F:
                Laya.stage.event(D.NextStep_Event);
                break;
            case Laya.Keyboard.Q:
                this.blow();
                break;
            case Laya.Keyboard.SPACE:
                this.findPath();
                break;
        }
    }
}